<template>
  <el-space fill size="large">
    <el-card>
      <el-form :inline="true" class="form">
        <el-form-item>
          <div class="search">
            <el-select style="width: 160px" v-model="key">
              <el-option
                v-for="item in selectOptions"
                :key="item.value"
                :label="item.lable"
                :value="item.value"></el-option>
            </el-select>
            <el-input
              :placeholder="`请输入搜索${selectStr}`"
              v-model.trim="val"></el-input>
          </div>
        </el-form-item>

        <el-form-item>
          <el-button
            type="primary"
            :loading="loading"
            :icon="Search"
            :disabled="val == ''"
            @click="handleSearch"
            >搜索</el-button
          >
          <el-button :icon="Refresh" @click="reset" :loading="loading"
            >重置</el-button
          >
        </el-form-item>
      </el-form>
    </el-card>
    <el-card>
      <el-button color="#626aef" :icon="DocumentAdd" @click="handleAdd"
        >新增用户</el-button
      >
      <el-button
        type="danger"
        :icon="FolderDelete"
        :disabled="selectUsers.length ? false : true"
        @click="handleBulkDel"
        >批量删除</el-button
      >
      <el-table
        style="margin: 10px 0"
        :data="tableData"
        @selection-change="selectChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column label="#" type="index"></el-table-column>
        <el-table-column
          label="id"
          property="_id"
          header-align="center"
          show-overflow-tooltip></el-table-column>
        <el-table-column
          label="用户昵称"
          min-width="120"
          align="center"
          property="name"
          header-align="center"></el-table-column>
        <el-table-column
          label="用户账号"
          align="center"
          property="username"
          min-width="120"
          header-align="center"></el-table-column>
        <el-table-column
          label="用户角色"
          property="roleNames"
          min-width="160"
          show-overflow-tooltip></el-table-column>
        <el-table-column
          label="创建时间"
          align="center"
          property="createdAt"
          header-align="center"
          show-overflow-tooltip></el-table-column>
        <el-table-column
          label="更新时间"
          align="center"
          property="updatedAt"
          show-overflow-tooltip
          header-align="center"></el-table-column>
        <el-table-column label="操作" width="180" header-align="center">
          <template #default="{ row }">
            <el-row style="margin-left: 15px">
              <el-tooltip content="分配角色" placement="bottom" effect="light">
                <el-button
                  :icon="User"
                  type="success"
                  circle
                  @click="assignRole(row)"></el-button>
              </el-tooltip>
              <el-tooltip content="用户修改" placement="bottom" effect="light">
                <el-button
                  :icon="Edit"
                  type="primary"
                  circle
                  @click="handleUpdate(row)"></el-button>
              </el-tooltip>
              <el-popconfirm
                :title="`你确定要删除${row.niceName}吗？`"
                @confirm="delUser(row._id)"
                width="220px">
                <template #reference>
                  <el-button
                    :icon="Delete"
                    type="danger"
                    circle
                    :loading="loading"></el-button>
                </template>
              </el-popconfirm>
            </el-row>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[5, 10, 15, 20]"
        layout="prev, pager, next, jumper,->,sizes,total"
        :total="totalItem"
        :background="false"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange" />
    </el-card>
  </el-space>
  <el-drawer v-model="drawer" direction="rtl">
    <template #header>
      <h3>{{ isUpdate ? "编辑用户" : "新增用户" }}</h3>
    </template>
    <template #default>
      <div class="demo-drawer__content">
        <el-form :model="formData" ref="ruleFormRef" :rules="rules" status-icon>
          <el-form-item label="用户账号" label-width="80px" prop="username">
            <el-input
              v-model="formData.username"
              clearable
              placeholder="请输入一个新的账号" />
          </el-form-item>
          <el-form-item
            label="密码"
            label-width="80px"
            prop="password"
            v-if="!isUpdate">
            <el-input
              type="password"
              v-model="formData.password"
              clearable
              show-password
              placeholder="请输入一个密码" />
          </el-form-item>
          <el-form-item label="用户昵称" label-width="80px" prop="name">
            <el-input
              v-model="formData.name"
              clearable
              placeholder="请输入一个昵称" />
          </el-form-item>
        </el-form>
      </div>
    </template>
    <template #footer>
      <div class="demo-drawer__footer">
        <el-button
          type="primary"
          :loading="loading"
          @click="submitForm(ruleFormRef)">
          提交</el-button
        >
        <el-button @click="cancelForm">放弃</el-button>
      </div>
    </template>
  </el-drawer>
  <AssignSide ref="assignSide" />
</template>

<script setup lang="ts" name="User">
  import { ref, reactive, toRefs, onMounted, computed } from "vue";
  import {
    ElMessage,
    ElMessageBox,
    type FormInstance,
    type FormRules,
  } from "element-plus";
  import {
    Search,
    DocumentAdd,
    Delete,
    Edit,
    User,
    Refresh,
    FolderDelete,
  } from "@element-plus/icons-vue";
  import { storeToRefs } from "pinia";
  import { SelectKey } from "@/apis/acl/user";
  import type { IUserBase } from "@/apis/acl/user/type";
  import useLayoutSettingStore from "@/store/modules/setting";
  import useUserStore from "@/store/modules/user";
  import AssignSide from "./assignSide/index.vue";

  //#region 数据状态管理
  const assignSide = ref<InstanceType<typeof AssignSide> | null>(null);
  const layoutStore = useLayoutSettingStore();
  const userStore = useUserStore();
  const { tableData, loading, currentPage, pageSize, key, val, totalItem } =
    storeToRefs(userStore);
  const selectOptions = [
    {
      value: SelectKey.name,
      lable: "用户名",
    },
    {
      value: SelectKey.username,
      lable: "账号名",
    },
  ];

  const selectStr = computed(() => {
    return selectOptions.find(item => item.value === key.value)?.lable;
  });
  const ruleFormRef = ref<FormInstance>();

  const state = reactive<{
    formData: IUserBase;
    selectUsers: IUserBase[];
    isUpdate: boolean;
    drawer: boolean;
  }>({
    formData: { name: "" },
    selectUsers: [],
    isUpdate: false,
    drawer: false,
  });

  const { formData, selectUsers, isUpdate, drawer } = toRefs(state);

  onMounted(() => {
    getAllUser();
  });

  /**
   * 获取table数据
   * @param Page 当前页
   * @param size 页面允许的条数
   */
  const getAllUser = async (Page = 1) => {
    await userStore.getAllUser(Page);
  };
  //#endregion

  //#region 表单相关

  /** 表单校验规则 */
  const rules = reactive<FormRules<Pick<IUserBase, "username" | "password">>>({
    username: [
      {
        required: true,
        message: "用户名不能为空！",
        trigger: ["blur"],
      },
      {
        pattern: /^\w{5,10}$/,
        message: "用户名必须满足5~10英文字母或数字！",
        trigger: "blur",
      },
    ],
    password: [
      {
        required: true,
        message: "密码不能为空！",
        trigger: ["blur"],
      },
      {
        pattern: /^(?=[^0])(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9A-Za-z]{6,20}$/,
        message:
          "密码必须满足大小英文字母+数字组合方式,总长度6~20位,并且0不在首位!",
        trigger: "blur",
      },
    ],
  });

  //#endregion

  //#region 分页

  const handleSizeChange = (val: number) => {
    pageSize.value = val;
    currentPage.value = 1;
    getAllUser();
  };

  const handleCurrentChange = (val: number) => {
    currentPage.value = val;
    getAllUser(currentPage.value);
  };

  //#endregion

  //#region table操作按钮逻辑

  /** 执行搜索按钮逻辑 */
  const handleSearch = async () => {
    await getAllUser();
    val.value = "";
  };

  /** 执行重置刷新按钮逻辑 */
  const reset = () => {
    val.value = "";
    key.value = SelectKey.name;
    layoutStore.refresh = !layoutStore.refresh;
  };

  /** 执行增加用户按钮逻辑 */
  const handleAdd = () => {
    //显示抽屉
    drawer.value = true;
    isUpdate.value = false;
    //清空表单数据
    formData.value = { name: "" };

    ruleFormRef.value?.resetFields();
  };

  //批量删除
  const handleBulkDel = () => {
    let ids: string[] = [];
    ids = selectUsers.value.map((i: any) => i._id);
    if (ids.length == 0) {
      ElMessage.warning("请选择要删除的用户！");
      return;
    }

    ElMessageBox.confirm("此操作将永久删除该批用户, 是否继续?", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(async () => {
        await userStore.bulkDeleteUser(ids);
      })
      .catch(() => {
        ElMessage.info("已取消删除");
      });
  };

  /** 分配角色按钮逻辑 */
  const assignRole = async (row: IUserBase) => {
    assignSide.value?.isOpen(row);
  };

  /** 执行编辑用户按钮逻辑 */
  const handleUpdate = (row: IUserBase) => {
    //显示抽屉
    drawer.value = true;
    //清空表单数据
    formData.value = { name: "" };
    isUpdate.value = true;

    //回显数据
    Object.assign(formData.value, row);
  };

  /** 执行删除用户按钮逻辑 */
  const delUser = async (id: string) => {
    await userStore.deleteUser(id);
  };

  /** table复选框勾选执行的逻辑 */
  const selectChange = (val: any) => {
    selectUsers.value = val;
  };
  //#endregion

  //#region drawer增加或修改
  /** 执行提交按钮逻辑 */
  const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    const valid = await formEl.validate();
    if (!valid) {
      ElMessage.error("请按照要求填写表单！");
      return;
    }

    //执行添加或修改用户api请求
    await UpdateOrAddData(formData.value);
    drawer.value = false;
    //浏览器自动刷新页面
    // window.location.reload();
    getAllUser();
  };

  /** 编辑或增加api请求，依据data数据携带_id的情况判断 */
  const UpdateOrAddData = async (data: IUserBase) => {
    await userStore.addOrUpdateUser(data);
  };

  /** 抽屉取消按钮逻辑 */
  const cancelForm = () => {
    drawer.value = false;
  };
  //#endregion
</script>

<style scoped lang="scss">
  .form {
    /* 弹性布局 水平两边 垂直居中;*/
    display: flex;
    justify-content: space-between;
    align-items: center;
    .search {
      display: flex;
      align-items: center;
      gap: 10px;
    }
  }
</style>
